﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows;
using System.ServiceModel;

namespace cs2335lab5
{
    namespace Client
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
            /// <summary>
            /// our handle on the LoginForm
            /// </summary>
            private LoginForm login;

            /// <summary>
            /// our handle to the ClientForm
            /// </summary>
            private ClientForm client;

            /// <summary>
            /// our handle to the IssueDetail window
            /// </summary>
            private IssueDetail idetail;

            /// <summary>
            /// our handle to the UserDetail window
            /// </summary>
            private UserDetail udetail;

            /// <summary>
            /// TCP-based proxy to the server object
            /// </summary>
            protected Data.INetworkManager TcpProxy;

            /// <summary>
            /// A public proxy for external classes to use
            /// This can be easily changed to another proxy
            /// </summary>
            public Data.INetworkManager Proxy
            {
                get
                {
                    return TcpProxy;
                }
                set
                {
                    TcpProxy = value;
                }
            }

            /// <summary>
            /// The callback object
            /// </summary>
            public NetworkManagerCallback Callback { get; protected set; }

            /// <summary>
            /// the data related to the current user of the application
            /// </summary>
            public Data.User User { get; set; }

            /// <summary>
            /// Our constructor: we're opening up a login form
            /// </summary>
            public App()
                : base()
            {
                
            }

            /// <summary>
            /// Code to execute on startup
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="args"></param>
            void AppStartup(object sender, StartupEventArgs args)
            {
                ShowLogin();
            }

            /// <summary>
            /// Shows the login dialog box and hides any other dialog boxes
            /// </summary>
            public void ShowLogin()
            {
                // hide the client dialog box
                if (client != null)
                {
                    client.Hide();
                }

                // show the login dialog box
                if (login == null)
                {
                    login = new LoginForm();
                }
                login.Reset();
                login.Show();
            }

            /// <summary>
            /// Hides the login dialog and shows the client
            /// </summary>
            public void ShowClient()
            {
                // hide the login dialog box
                if (login != null)
                {
                    login.Hide();
                }

                // show the client
                UpdateClient();
            }

            /// <summary>
            /// Tell the client to update itself
            /// </summary>
            public void UpdateClient()
            {
                if (client == null)
                {
                    client = new ClientForm();
                }
                client.Reset();
                client.Show();
            }

            /// <summary>
            /// Opens the IssueDetail form to a specific issue
            /// on the server (gets it with provided key)
            /// </summary>
            /// <param name="id"></param>
            public void ShowIssueDetail(Int64? id)
            {
                // make sure the login dialog is hidden
                if (login != null)
                {
                    login.Hide();
                }

                // show the detail box
                if (idetail == null)
                {
                    idetail = new IssueDetail();
                }

                // show the dialog if it isn't already
                idetail.Show();

                // load the issue
                idetail.Load(id);

                // bring it to front
                idetail.Activate();
            }

            /// <summary>
            /// Opens the UserDetail form to a specific user
            /// (data from the server, use provided key)
            /// </summary>
            /// <param name="id"></param>
            public void ShowUserDetail(string id)
            {
                // make sure the login window is hidden
                if (login != null)
                {
                    login.Hide();
                }

                // show the detail box
                if (udetail == null)
                {
                    udetail = new UserDetail();
                }

                // show the dialog if it isn't already
                udetail.Show();

                // load the issue
                udetail.Load(id);

                // bring it to the front
                udetail.Activate();
            }

            /// <summary>
            /// Extra Connect handler to take a string server, int port
            /// </summary>
            /// <param name="server"></param>
            /// <param name="port"></param>
            public void Connect(string server, int port)
            {
                Connect(server, Convert.ToString(port));
            }

            /// <summary>
            /// Connects to server
            /// </summary>
            /// <param name="server">IP address or hostname</param>
            /// <param name="port">Port</param>
            public void Connect(string server, string port)
            {
                // create the callback object
                if (Callback == null)
                {
                    Callback = new NetworkManagerCallback();
                }

                // create the tcp connection
                StringBuilder b = new StringBuilder("net.tcp://");
                b.Append(server);
                b.Append(":");
                if (port.CompareTo("") != 0)
                {
                    b.Append(port);
                }
                else
                {
                    b.Append("41337");
                }
                b.Append("/TcpIssueManager");
                DuplexChannelFactory<Data.INetworkManager> tcpFactory = new DuplexChannelFactory<Data.INetworkManager>(
                    Callback, new NetTcpBinding(), new EndpointAddress(b.ToString()));

                TcpProxy = tcpFactory.CreateChannel();
            }

            /// <summary>
            /// Disconnects from the server
            /// </summary>
            public void Disconnect()
            {
                if (Proxy != null && Proxy.Connected())
                {
                    Proxy.LogOut(User);
                }

                Proxy = null;
            }

            /// <summary>
            /// Singleton method to access the App-specific functions 
            /// without needing to cast
            /// </summary>
            /// <returns></returns>
            public static App Instance()
            {
                return ((App)App.Current);
            }
        }
    }
}